Skip to content

Refactor overlay#1643

Merged
ComixHe merged 3 commits into
OpenAtom-Linyaps:masterfrom
reddevillg:refactor_overlay
Apr 22, 2026
Merged

Refactor overlay#1643
ComixHe merged 3 commits into
OpenAtom-Linyaps:masterfrom
reddevillg:refactor_overlay

Conversation

@reddevillg

Copy link
Copy Markdown
Collaborator

No description provided.

Signed-off-by: reddevillg <reddevillg@gmail.com>
- support kernel/FUSE mode in OverlayFS
- support multiple lowerdirs and optional upper/work dirs

Signed-off-by: reddevillg <reddevillg@gmail.com>
@deepin-ci-robot

Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: reddevillg

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a major refactoring of the container runtime and package management system, introducing a structured RunContextConfig and a new InitRunContext DBus interface. Key changes include a new OverlayFSDriver supporting both Kernel and FUSE modes, a refactored ContainerBuilder for specialized container lifecycles, and enhanced namespace support with UID/GID mapping. Feedback identifies a potential null pointer dereference in the package manager's task handling and a race condition in the CLI process startup due to hardcoded sleeps. Additionally, the review highlights thread-safety concerns in the OverlayFS mounting logic, suggests replacing perror with structured error results in library code, and recommends ensuring consistent timezone defaults when /etc/localtime is a regular file.

return toDBusReply(task);
}

auto &taskRef = task->get();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The code accesses the task object without verifying if the underlying pointer is valid. If addPackageTask returns a successful result but the task pointer itself is null, this will lead to a crash when calling taskRef.taskID().

LINGLONG_LIBEXEC_DIR "/ll-package-manager",
"--no-dbus" });
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using a hardcoded sleep (std::this_thread::sleep_for(1s)) to wait for a detached process to initialize is a known anti-pattern that introduces race conditions. It is better to implement a polling mechanism with a timeout that checks for the existence of the communication socket or another readiness indicator.


if (dup2(stdinPipe[0], STDIN_FILENO) == -1) {
perror(("dup2 stdin failed for " + command).c_str());
perror(fmt::format("dup2 stdin failed for {}", command).c_str());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using perror in library code is generally discouraged as it prints directly to stderr. It is better to capture the error message and return it via the utils::error::Result type, allowing the caller to handle logging appropriately.

Comment on lines +631 to +634
contextCfg.timezone = "";
return LINGLONG_OK;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If /etc/localtime is a regular file instead of a symlink, the timezone is set to an empty string. This behavior differs from the case where the file is missing (where it defaults to 'UTC'). Consider if a default value like 'UTC' should be used here as well to ensure consistency.

Comment on lines +68 to 71
if (mounted_) {
LogW("OverlayFS already mounted at {}", merged_.string());
return false;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The mount() method is not thread-safe. Multiple threads calling mount() simultaneously could bypass the mounted_ check and attempt to mount the filesystem multiple times. Consider using a mutex or an atomic flag to protect the mounting state.

@codecov

codecov Bot commented Apr 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 6.49943% with 1640 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...inglong/src/linglong/runtime/container_builder.cpp 2.17% 270 Missing ⚠️
libs/linglong/src/linglong/cli/cli.cpp 0.79% 250 Missing ⚠️
...glong/oci-cfg-generators/container_cfg_builder.cpp 0.00% 218 Missing ⚠️
libs/utils/src/linglong/utils/namespace.cpp 0.00% 169 Missing ⚠️
libs/linglong/src/linglong/runtime/run_context.cpp 23.76% 61 Missing and 93 partials ⚠️
...g/src/linglong/package_manager/package_manager.cpp 3.20% 150 Missing and 1 partial ⚠️
apps/ll-package-manager/src/main.cpp 0.00% 111 Missing ⚠️
libs/linglong/src/linglong/runtime/container.cpp 0.00% 88 Missing ⚠️
libs/utils/src/linglong/utils/overlayfs.cpp 12.08% 78 Missing and 2 partials ⚠️
...linglong/src/linglong/builder/linglong_builder.cpp 0.00% 74 Missing ⚠️
... and 10 more
Files with missing lines Coverage Δ
libs/linglong/src/linglong/cli/cli.h 7.69% <ø> (-0.65%) ⬇️
...ong/src/linglong/package_manager/package_manager.h 0.00% <ø> (ø)
...linglong/src/linglong/runtime/security_context.cpp 0.00% <ø> (ø)
libs/utils/src/linglong/utils/overlayfs.h 100.00% <100.00%> (+100.00%) ⬆️
libs/utils/src/linglong/utils/runtime_config.cpp 25.00% <0.00%> (ø)
libs/common/src/linglong/common/dir.cpp 30.00% <0.00%> (-1.25%) ⬇️
.../linglong/src/linglong/package/fuzzy_reference.cpp 64.81% <50.00%> (-2.58%) ⬇️
libs/linglong/src/linglong/runtime/run_context.h 77.77% <50.00%> (+37.77%) ⬆️
apps/ll-builder/src/main.cpp 0.00% <0.00%> (ø)
...s/linglong/src/linglong/runtime/overlayfs_driver.h 72.72% <72.72%> (ø)
... and 14 more

... and 81 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Changes:
- Add InitRunContext D-Bus method for preparing container cache before run
- Introduce OverlayFSDriver abstraction with kernel and FUSE implementations
- Enter new user namespace and mount namespace before setup overlayfs
- Refactor ContainerBuilder to support init, build, and run container modes
- Add unit tests for OverlayFSDriver and RunContext

Signed-off-by: reddevillg <reddevillg@gmail.com>
@deepin-ci-robot

Copy link
Copy Markdown
Collaborator

deepin pr auto review

代码审查报告

总体评价

这次提交包含大量代码变更,主要涉及容器运行时、包管理和CLI工具的重构。代码整体质量较高,但存在一些可以改进的地方。

主要变更点

  1. 引入了新的RunContextConfig配置系统
  2. 重构了容器构建流程
  3. 添加了OverlayFS驱动支持
  4. 改进了命名空间处理
  5. 优化了包管理器与CLI的交互

具体问题与建议

1. 语法与逻辑问题

问题1:在libs/linglong/src/linglong/cli/cli.cpp中,getPkgMan()方法可能返回空指针

auto pkgMan = this->getPkgMan();
if (!pkgMan) {
    this->printer.printErr(pkgMan.error());
    return -1;
}

auto pendingReply = (*pkgMan)->InstallFromFile(...);

建议:虽然代码已经检查了返回值,但建议在getPkgMan()方法内部确保返回的指针总是有效的,或者使用智能指针替代原始指针。

问题2:在libs/linglong/src/linglong/runtime/container.cpp中,ContainerContext析构函数中的清理逻辑可能不完整

ContainerContext::~ContainerContext()
{
    if (this->overlayFS) {
        this->overlayFS->unmount();
    }

    if (getenv("LINGLONG_DEBUG") == nullptr && !this->bundleDir.empty()) {
        std::error_code ec;
        std::filesystem::remove_all(this->bundleDir, ec);
        if (ec) {
            LogW("failed to remove bundle directory {}: {}", this->bundleDir, ec.message());
        }
    }
}

建议:在卸载OverlayFS后,应该检查卸载是否成功,如果失败应该记录错误。此外,建议在删除目录前先确认目录是否为空。

2. 代码质量问题

问题1:在libs/linglong/src/linglong/runtime/container_builder.cpp中,prepareContainer方法过于复杂

auto ContainerBuilder::prepareContainer(runtime::RunContext &context,
                                        ContainerMode mode,
                                        const CommonContainerOptions &options) noexcept
  -> utils::error::Result<PreparedContainer>
{
    // 大量代码...
}

建议:考虑将这个方法拆分成更小的函数,每个函数负责一个特定的任务,提高代码可读性和可维护性。

问题2:在libs/linglong/src/linglong/runtime/overlayfs_driver.cpp中,错误处理不够一致

auto OverlayFSDriver::createOverlayFS(...) noexcept
  -> utils::error::Result<std::unique_ptr<utils::OverlayFS>>
{
    // ...
    auto result = prepare(...);
    if (!result) {
        return LINGLONG_ERR("prepare overlayfs", result);
    }
    // ...
}

建议:统一错误处理方式,确保所有错误都包含足够的上下文信息,便于调试。

3. 性能问题

问题1:在libs/linglong/src/linglong/runtime/run_context.cpp中,resolve方法可能存在性能问题

utils::error::Result<void> RunContext::resolve(const api::types::v1::RunContextConfig &config)
{
    // 大量文件系统操作和解析...
}

建议:考虑添加缓存机制,避免重复解析相同的配置。对于频繁访问的文件系统路径,可以缓存其状态。

问题2:在libs/linglong/src/linglong/runtime/overlayfs_driver.cpp中,detectKernelOverlaySupport方法每次都读取文件

auto OverlayFSDriver::detectKernelOverlaySupport() noexcept -> OverlaySupport
{
    std::ifstream filesystems("/proc/filesystems");
    // ...
    std::ifstream version("/proc/version");
    // ...
}

建议:这个方法的结果在运行时不会改变,可以考虑缓存检测结果。

4. 安全问题

问题1:在libs/linglong/src/linglong/runtime/container_builder.cpp中,normalizeContainerRootfs方法存在安全风险

auto ContainerBuilder::normalizeContainerRootfs(
  const std::filesystem::path &rootfs, const api::types::v1::RunContextConfig &config) noexcept
  -> utils::error::Result<void>
{
    std::vector<std::filesystem::path> remove{
        "/etc/localtime",
        "/etc/resolv.conf",
    };

    for (const auto &r : remove) {
        std::error_code ec;
        auto target = rootfs / (r.is_absolute() ? r.relative_path() : r);
        if (std::filesystem::exists(target, ec)) {
            std::filesystem::remove(target, ec);
            // ...
        }
    }
    // ...
}

建议:在删除文件前,应该验证文件确实是由容器管理器创建的,避免意外删除重要系统文件。可以考虑使用特定的标记或目录结构来标识这些文件。

问题2:在libs/linglong/src/linglong/utils/namespace.cpp中,runInNamespace方法中的权限提升逻辑需要更严格的检查

if (targetUid != 0) {
    auto res = prepareAmbientCapabilities();
    if (!res) {
        LogE("failed to prepare ambient capabilities for uid {}: {}",
             targetUid,
             res.error().message());
        return -1;
    }

    if (setuid(targetUid) == -1) {
        LogE("setuid failed: {}", common::error::errorString(errno));
        return -1;
    }
    // ...
}

建议:在提升权限前,应该验证调用者是否有权限执行此操作。可以考虑添加额外的审计日志,记录所有权限提升操作。

5. 其他建议

  1. 文档:建议为新增的RunContextConfigOverlayFSDriver类添加更详细的文档说明,特别是它们的使用场景和限制。

  2. 测试:虽然添加了一些测试用例,但建议增加更多边界条件和错误场景的测试,特别是对于OverlayFS和命名空间相关的功能。

  3. 错误处理:建议统一错误处理策略,特别是在涉及系统调用和文件系统操作的地方,确保所有可能的错误都被正确处理和记录。

  4. 日志:建议增加更详细的日志记录,特别是在容器创建和销毁的关键路径上,便于问题诊断。

  5. 配置验证:建议在RunContextConfig解析后添加验证逻辑,确保配置的有效性和一致性,避免在运行时才发现配置问题。

总结

这次提交包含大量有价值的改进,特别是容器运行时和包管理器的重构。代码整体质量较高,但在错误处理、性能优化和安全性方面还有一些改进空间。建议在合并前重点关注上述提到的问题,特别是安全相关的部分。

@reddevillg reddevillg requested review from ComixHe and dengbo11 April 22, 2026 02:15
@ComixHe ComixHe merged commit 5feeeb3 into OpenAtom-Linyaps:master Apr 22, 2026
16 of 17 checks passed
@reddevillg reddevillg deleted the refactor_overlay branch April 22, 2026 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants